<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  <title>Hexo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="第二十八章Redis第1节 Redis环境搭建 redis_概述   redis   概念：redis是一款高性能的NOSQL系列的非关系型数据库  1.1.什么是NOSQL  NoSQL(NoSQL &#x3D; Not Only SQL)，意即“不仅仅是SQL”，是一项全新的数据库理念，泛指非关系型的数据库。 随着互联网web2.0网站的兴起，传统的关系数据库在应付web2.0网站，特别是超大规模和高并">
<meta property="og:type" content="article">
<meta property="og:title" content="Hexo">
<meta property="og:url" content="https://goofyer.gitee.io/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E4%BA%8C%E5%8D%81%E5%85%AB%E7%AB%A0Redis/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="第二十八章Redis第1节 Redis环境搭建 redis_概述   redis   概念：redis是一款高性能的NOSQL系列的非关系型数据库  1.1.什么是NOSQL  NoSQL(NoSQL &#x3D; Not Only SQL)，意即“不仅仅是SQL”，是一项全新的数据库理念，泛指非关系型的数据库。 随着互联网web2.0网站的兴起，传统的关系数据库在应付web2.0网站，特别是超大规模和高并">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="2021-12-19T17:37:10.059Z">
<meta property="article:modified_time" content="2021-12-19T17:37:10.060Z">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/notes-on-computer-expertise/atom.xml" title="Hexo" type="application/atom+xml">
  
  
    <link rel="shortcut icon" href="/notes-on-computer-expertise/favicon.png">
  
  
    
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-source-code-pro@0.0.71/index.min.css">

  
  
<link rel="stylesheet" href="/notes-on-computer-expertise/css/style.css">

  
    
<link rel="stylesheet" href="/notes-on-computer-expertise/fancybox/jquery.fancybox.min.css">

  
<meta name="generator" content="Hexo 5.4.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/notes-on-computer-expertise/" id="logo">Hexo</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/notes-on-computer-expertise/">Home</a>
        
          <a class="main-nav-link" href="/notes-on-computer-expertise/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/notes-on-computer-expertise/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="https://goofyer.gitee.io/notes-on-computer-expertise"></form>
      </div>
    </div>
  </div>
</header>

      <div class="outer">
        <section id="main"><article id="post-Java/第二十八章Redis" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E4%BA%8C%E5%8D%81%E5%85%AB%E7%AB%A0Redis/" class="article-date">
  <time class="dt-published" datetime="2021-12-19T17:37:10.059Z" itemprop="datePublished">2021-12-20</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h2 id="第二十八章Redis"><a href="#第二十八章Redis" class="headerlink" title="第二十八章Redis"></a>第二十八章Redis</h2><h3 id="第1节-Redis环境搭建"><a href="#第1节-Redis环境搭建" class="headerlink" title="第1节 Redis环境搭建"></a>第1节 Redis环境搭建</h3><ul>
<li><p>redis_概述</p>
<ul>
<li><ol>
<li><p>redis</p>
<ul>
<li><ol>
<li><p>概念：redis是一款高性能的NOSQL系列的非关系型数据库</p>
<ul>
<li><p>1.1.什么是NOSQL</p>
<ul>
<li>NoSQL(NoSQL = Not Only SQL)，意即“不仅仅是SQL”，是一项全新的数据库理念，泛指非关系型的数据库。</li>
<li>随着互联网web2.0网站的兴起，传统的关系数据库在应付web2.0网站，特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心，暴露了很多难以克服的问题，而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战，尤其是大数据应用难题。</li>
<li><p>1.1.1 NOSQL和关系型数据库比较</p>
<ul>
<li><p>优点：</p>
<ul>
<li>1）成本：nosql数据库简单易部署，基本都是开源软件，不需要像使用oracle那样花费大量成本购买使用，相比关系型数据库价格便宜。</li>
<li>2）查询速度：nosql数据库将数据存储于缓存之中，关系型数据库将数据存储在硬盘中，自然查询速度远不及nosql数据库。</li>
<li>3）存储数据的格式：nosql的存储格式是key,value形式、文档形式、图片形式等等，所以可以存储基础类型以及对象或者是集合等各种格式，而数据库则只支持基础类型。</li>
<li>4）扩展性：关系型数据库有类似join这样的多表查询机制的限制导致扩展很艰难。</li>
</ul>
</li>
<li><p>缺点：</p>
<ul>
<li>1）维护的工具和资料有限，因为nosql是属于新的技术，不能和关系型数据库十几年的技术同日而语。</li>
<li>2）不提供对sql的支持，如果不支持sql这样的工业标准，将产生一定用户的学习和使用成本。</li>
<li>3）不提供关系型数据库对事务的处理。</li>
</ul>
</li>
</ul>
</li>
<li><p>1.1.2.非关系型数据库的优势：</p>
<ul>
<li>1）性能NOSQL是基于键值对的，可以想象成表中的主键和值的对应关系，而且不需要经过SQL层的解析，所以性能非常高。</li>
<li>2）可扩展性同样也是因为基于键值对，数据之间没有耦合性，所以非常容易水平扩展。</li>
</ul>
</li>
<li><p>1.1.3.关系型数据库的优势：</p>
<ul>
<li>1）复杂查询可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。</li>
<li>2）事务支持使得对于安全性能很高的数据访问要求得以实现。对于这两类数据库，对方的优势就是自己的弱势，反之亦然。</li>
</ul>
</li>
<li><p>1.1.4.总结</p>
<ul>
<li>关系型数据库与NoSQL数据库并非对立而是互补的关系，即通常情况下使用关系型数据库，在适合使用NoSQL的时候使用NoSQL数据库，</li>
<li>让NoSQL数据库对关系型数据库的不足进行弥补。</li>
<li>一般会将数据存储在关系型数据库中，在nosql数据库中备份存储关系型数据库的数据</li>
</ul>
</li>
</ul>
</li>
<li><p>1.2.主流的NOSQL产品</p>
<ul>
<li><p>键值(Key-Value)存储数据库</p>
<ul>
<li>相关产品： Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB</li>
<li>典型应用： 内容缓存，主要用于处理大量数据的高访问负载。 </li>
<li>数据模型： 一系列键值对</li>
<li>优势： 快速查询</li>
<li>劣势： 存储的数据缺少结构化</li>
</ul>
</li>
<li><p>列存储数据库</p>
<ul>
<li>相关产品：Cassandra, HBase, Riak</li>
<li>典型应用：分布式的文件系统</li>
<li>数据模型：以列簇式存储，将同一列数据存在一起</li>
<li>优势：查找速度快，可扩展性强，更容易进行分布式扩展</li>
<li>劣势：功能相对局限</li>
</ul>
</li>
<li><p>文档型数据库</p>
<ul>
<li>相关产品：CouchDB、MongoDB</li>
<li>典型应用：Web应用（与Key-Value类似，Value是结构化的）</li>
<li>数据模型： 一系列键值对</li>
<li>优势：数据结构要求不严格</li>
<li>劣势： 查询性能不高，而且缺乏统一的查询语法</li>
</ul>
</li>
<li><p>图形(Graph)数据库</p>
<ul>
<li>相关数据库：Neo4J、InfoGrid、Infinite Graph</li>
<li>典型应用：社交网络</li>
<li>数据模型：图结构</li>
<li>优势：利用图结构相关算法。</li>
<li>劣势：需要对整个图做计算才能得出结果，不容易做分布式的集群方案。</li>
</ul>
</li>
</ul>
</li>
<li><p>1.3 什么是Redis</p>
<ul>
<li>Redis是用C语言开发的一个开源的高性能键值对（key-value）数据库，官方提供测试数据，50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s ，且Redis通过提供多种键值数据类型来适应不同场景下的存储需求，</li>
<li><p>Redis支持的键值数据类型如下：</p>
<ul>
<li>1) 字符串类型 string</li>
<li>2) 哈希类型 hash</li>
<li>3) 列表类型 list</li>
<li>4) 集合类型 set</li>
<li>5) 有序集合类型 sortedset</li>
</ul>
</li>
<li><p>1.3.1 redis的应用场景</p>
<ul>
<li>缓存（数据查询、短连接、新闻内容、商品内容等等）</li>
<li>聊天室的在线好友列表</li>
<li>任务队列。（秒杀、抢购、12306等等）</li>
<li>应用排行榜</li>
<li>网站访问统计</li>
<li>数据过期处理（可以精确到毫秒）</li>
<li>分布式集群架构中的session分离</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>下载安装</p>
<ul>
<li><ol>
<li>官网：<a target="_blank" rel="noopener" href="https://redis.io">https://redis.io</a></li>
</ol>
</li>
<li><ol>
<li>中文网：<a target="_blank" rel="noopener" href="http://www.redis.net.cn/">http://www.redis.net.cn/</a></li>
</ol>
</li>
<li><ol>
<li>解压直接可以使用：</li>
</ol>
<ul>
<li><ul>
<li>redis.windows.conf：配置文件</li>
</ul>
</li>
<li><ul>
<li>redis-cli.exe：redis的客户端</li>
</ul>
</li>
<li><ul>
<li>redis-server.exe：redis服务器端</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>命令操作</p>
<ul>
<li><ol>
<li>数据结构</li>
</ol>
<ul>
<li><ul>
<li><p>redis存储的是：key,value格式的数据（键值对），其中key都是字符串，value有5种不同的数据结构。</p>
<ul>
<li><ul>
<li><p>value的数据结构：</p>
<ul>
<li>1) 字符串类型 string：最常用</li>
<li>2) 哈希类型 hash ：map格式  </li>
<li>3) 列表类型 list ：linkedlist格式，支持重复元素</li>
<li>4) 集合类型 set  ：不允许重复元素</li>
<li>5) 有序集合类型 sortedset：不允许重复元素，且元素有顺序</li>
</ul>
</li>
</ul>
</li>
<li><p>字符串类型 string</p>
<ul>
<li><ol>
<li>存储： set key value</li>
</ol>
</li>
<li><ol>
<li>获取： get key</li>
</ol>
</li>
<li><ol>
<li>删除： del key</li>
</ol>
</li>
</ul>
</li>
<li><p>哈希类型 hash</p>
<ul>
<li><ol>
<li>存储： hset key field value</li>
</ol>
</li>
<li><ol>
<li><p>获取： </p>
<ul>
<li><ul>
<li>hget key field: 获取指定的field对应的值</li>
</ul>
</li>
<li><ul>
<li>hgetall key：获取所有的field和value</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li>删除： hdel key field</li>
</ol>
</li>
</ul>
</li>
<li><p>列表类型 list：可以添加一个元素到列表的头部（左边）或者尾部（右边）。</p>
<ul>
<li><ol>
<li><p>添加：</p>
<ul>
<li><ol>
<li>lpush key value：将元素加入列表左表</li>
</ol>
</li>
<li><ol>
<li>rpush key value：将元素加入列表右边</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>获取：</p>
<ul>
<li><ul>
<li>lrange key start end：范围获取</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>删除：</p>
<ul>
<li><ul>
<li>lpop key： 删除列表最左边的元素，并将元素返回。</li>
</ul>
</li>
<li><ul>
<li>rpop key： 删除列表最右边的元素，并将元素返回。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
<li><p>有序集合类型 sortedset：不允许重复元素，且元素有顺序.每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。</p>
<ul>
<li><ol>
<li>存储：zadd key score value</li>
</ol>
</li>
<li><ol>
<li>获取：zrange key start end [withscores]</li>
</ol>
</li>
<li><ol>
<li>删除：zrem key value</li>
</ol>
</li>
</ul>
</li>
<li><ol>
<li><p>集合类型 set ： 不允许重复元素。</p>
<ul>
<li><ol>
<li>存储：sadd key value</li>
</ol>
</li>
<li><ol>
<li>获取：smembers key:获取set集合中所有元素</li>
</ol>
</li>
<li><ol>
<li>删除：srem key value:删除set集合中的某个元素    </li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>通用命令</p>
<ul>
<li><ol>
<li>keys *：查询所有的键</li>
</ol>
</li>
<li><ol>
<li>type key：获取键对应的value的类型</li>
</ol>
</li>
<li><ol>
<li>del key：删除指定的key value</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>持久化操作</p>
<ul>
<li><ol>
<li>redis是一个内存数据库，当redis服务器重启，获取电脑重启，数据会丢失，我们可以将redis内存中的数据持久化保存到硬盘的文件中。</li>
</ol>
</li>
<li><ol>
<li>redis持久化机制：</li>
</ol>
<ul>
<li><ol>
<li><p>RDB：默认方式，不需要进行配置，默认就使用这种机制。</p>
<ul>
<li><ul>
<li>在一定的间隔时间中，检测key的变化情况，然后持久化数据。</li>
</ul>
</li>
<li><ol>
<li><p>编辑redis.windwos.conf文件</p>
<ul>
<li><h1 id="after-900-sec-15-min-if-at-least-1-key-changed-在15min后，若有1个key发生改变就持久化一次。"><a href="#after-900-sec-15-min-if-at-least-1-key-changed-在15min后，若有1个key发生改变就持久化一次。" class="headerlink" title="after 900 sec (15 min) if at least 1 key changed // 在15min后，若有1个key发生改变就持久化一次。"></a>after 900 sec (15 min) if at least 1 key changed // 在15min后，若有1个key发生改变就持久化一次。</h1></li>
<li>save 900 1</li>
<li><h1 id="after-300-sec-5-min-if-at-least-10-keys-changed-在5min后，若有10个key发生改变就持久化一次。"><a href="#after-300-sec-5-min-if-at-least-10-keys-changed-在5min后，若有10个key发生改变就持久化一次。" class="headerlink" title="after 300 sec (5 min) if at least 10 keys changed // 在5min后，若有10个key发生改变就持久化一次。"></a>after 300 sec (5 min) if at least 10 keys changed // 在5min后，若有10个key发生改变就持久化一次。</h1></li>
<li>save 300 10</li>
<li><h1 id="after-60-sec-if-at-least-10000-keys-changed-在1min后，若有10000个key发生改变就持久化一次。"><a href="#after-60-sec-if-at-least-10000-keys-changed-在1min后，若有10000个key发生改变就持久化一次。" class="headerlink" title="after 60 sec if at least 10000 keys changed // 在1min后，若有10000个key发生改变就持久化一次。"></a>after 60 sec if at least 10000 keys changed // 在1min后，若有10000个key发生改变就持久化一次。</h1></li>
<li>save 60 10000</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>重新启动redis服务器，并指定配置文件名称</p>
<ul>
<li>D:\JavaWeb2018\day23_redis\资料\redis\windows-64\redis-2.8.9&gt;redis-server.exe redis.windows.conf    </li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li>AOF：日志记录的方式，可以记录每一条命令的操作。可以在每一次命令操作后，持久化数据。</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>使用Java客户端操作redis</p>
<ul>
<li><ul>
<li>Jedis: 一款java操作redis数据库的工具。</li>
</ul>
</li>
<li><ul>
<li>使用步骤：</li>
</ul>
<ul>
<li><ol>
<li>下载jedis的jar包</li>
</ol>
</li>
<li><ol>
<li>使用</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
<h3 id="第5节-Jedis连接池"><a href="#第5节-Jedis连接池" class="headerlink" title="第5节 Jedis连接池"></a>第5节 Jedis连接池</h3><ul>
<li>jedis连接池：JedisPool 获取jedis客户端连接时，直接从连接池中获取，对连接有一个更好的复用与管理。</li>
<li><ul>
<li><p>使用：</p>
<ul>
<li><ol>
<li>创建JedisPool连接池对象</li>
</ol>
</li>
<li><ol>
<li>调用方法 getResource()方法获取Jedis连接</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><h1 id="最大活动对象数"><a href="#最大活动对象数" class="headerlink" title="最大活动对象数"></a>最大活动对象数</h1><p>redis.pool.maxTotal=1000    </p>
<h1 id="最大能够保持idel状态的对象数"><a href="#最大能够保持idel状态的对象数" class="headerlink" title="最大能够保持idel状态的对象数"></a>最大能够保持idel状态的对象数</h1><p>redis.pool.maxIdle=100  </p>
<h1 id="最小能够保持idel状态的对象数"><a href="#最小能够保持idel状态的对象数" class="headerlink" title="最小能够保持idel状态的对象数"></a>最小能够保持idel状态的对象数</h1><p>redis.pool.minIdle=50    </p>
<h1 id="当池内没有返回对象时，最大等待时间"><a href="#当池内没有返回对象时，最大等待时间" class="headerlink" title="当池内没有返回对象时，最大等待时间"></a>当池内没有返回对象时，最大等待时间</h1><p>redis.pool.maxWaitMillis=10000    </p>
<h1 id="当调用borrow-Object方法时，是否进行有效性检查"><a href="#当调用borrow-Object方法时，是否进行有效性检查" class="headerlink" title="当调用borrow Object方法时，是否进行有效性检查"></a>当调用borrow Object方法时，是否进行有效性检查</h1><p>redis.pool.testOnBorrow=true    </p>
<h1 id="当调用return-Object方法时，是否进行有效性检查"><a href="#当调用return-Object方法时，是否进行有效性检查" class="headerlink" title="当调用return Object方法时，是否进行有效性检查"></a>当调用return Object方法时，是否进行有效性检查</h1><p>redis.pool.testOnReturn=true  </p>
<h1 id="“空闲链接”检测线程，检测的周期，毫秒数。如果为负值，表示不运行“检测线程”。默认为-1"><a href="#“空闲链接”检测线程，检测的周期，毫秒数。如果为负值，表示不运行“检测线程”。默认为-1" class="headerlink" title="“空闲链接”检测线程，检测的周期，毫秒数。如果为负值，表示不运行“检测线程”。默认为-1."></a>“空闲链接”检测线程，检测的周期，毫秒数。如果为负值，表示不运行“检测线程”。默认为-1.</h1><p>redis.pool.timeBetweenEvictionRunsMillis=30000  </p>
<h1 id="向调用者输出“链接”对象时，是否检测它的空闲超时；"><a href="#向调用者输出“链接”对象时，是否检测它的空闲超时；" class="headerlink" title="向调用者输出“链接”对象时，是否检测它的空闲超时；"></a>向调用者输出“链接”对象时，是否检测它的空闲超时；</h1><p>redis.pool.testWhileIdle=true  </p>
<h1 id="对于“空闲链接”检测线程而言，每次检测的链接资源的个数。默认为3"><a href="#对于“空闲链接”检测线程而言，每次检测的链接资源的个数。默认为3" class="headerlink" title="对于“空闲链接”检测线程而言，每次检测的链接资源的个数。默认为3."></a>对于“空闲链接”检测线程而言，每次检测的链接资源的个数。默认为3.</h1><p>redis.pool.numTestsPerEvictionRun=50  </p>
<h1 id="redis服务器的IP"><a href="#redis服务器的IP" class="headerlink" title="redis服务器的IP"></a>redis服务器的IP</h1><p>redis.ip=xxxxxx  </p>
<h1 id="redis服务器的Port"><a href="#redis服务器的Port" class="headerlink" title="redis服务器的Port"></a>redis服务器的Port</h1><p>redis1.port=6379</p>
</li>
</ul>
<p>Jedis_连接池工具类</p>
<ul>
<li><p>连接池工具类 JedisPoolUtils.java</p>
<ul>
<li><p>/**</p>
<ul>
<li>JedisPool工具类</li>
<li>加载配置文件，配置连接池的参数</li>
<li>提供获取连接的方法<br>*/<br>public class JedisPoolUtils {<br>private static JedisPool jedisPool;</li>
</ul>
<p>static {<br>  //读取配置文件<br>  InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream(“jedis.properties”);<br>  //创建Properties对象<br>  Properties pro = new Properties();<br>  //关联文件<br>  try {</p>
<pre><code>  pro.load(is);
</code></pre><p>  } catch (IOException e) {</p>
<pre><code>  e.printStackTrace();
</code></pre><p>  }<br>  //获取数据，设置到JedisPoolConfig中<br>  JedisPoolConfig config = new JedisPoolConfig();<br>  //pro.getProperty(“maxTotal”)：获取的值是字符串，配置要求的是int值<br>  config.setMaxTotal(Integer.parseInt(pro.getProperty(“maxTotal”)));//最大连接数<br>  config.setMaxIdle(Integer.parseInt(pro.getProperty(“maxIdle”)));//最大空闲连接数<br>  //初始化JedisPool对象<br>  jedisPool = new JedisPool(config, pro.getProperty(“host”), Integer.parseInt(pro.getProperty(“port”)));<br>}</p>
<p>/**</p>
<ul>
<li>获取连接方法<br>*/<br>public static Jedis getJedis() {<br>return jedisPool.getResource();//获取连接<br>}</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="第6节-Redis案例"><a href="#第6节-Redis案例" class="headerlink" title="第6节 Redis案例"></a>第6节 Redis案例</h3><ul>
<li><p>案例_分析&amp;环境搭建</p>
<ul>
<li><p>案例需求：</p>
<ul>
<li><ol>
<li>提供index.html页面，页面中有一个省份（下拉列表）。</li>
</ol>
</li>
<li><ol>
<li>当页面加载完成后，发送ajax请求，加载所有省份。</li>
</ol>
</li>
</ul>
</li>
<li><p>代码</p>
<ul>
<li><p>day23.sql</p>
<ul>
<li>CREATE DATABASE day23; — 创建数据库<br>USE day23;                — 使用数据库<br>CREATE TABLE province(   — 创建表<br>id INT PRIMARY KEY AUTO_INCREMENT,<br>NAME VARCHAR(20) NOT NULL</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>);<br>— 插入数据<br>INSERT INTO province VALUES(NULL,’北京’);<br>INSERT INTO province VALUES(NULL,’上海’);<br>INSERT INTO province VALUES(NULL,’广州’);<br>INSERT INTO province VALUES(NULL,’陕西’);</p>
<pre><code>    - druid.properties

        - driverClassName=com.mysql.jdbc.Driver
</code></pre><p>url=jdbc:mysql:///day23<br>username=root<br>password=root<br>initialSize=5<br>maxActive=10<br>maxWait=3000</p>
<ul>
<li>案例_实现_查询数据库</li>
<li><p>案例_实现_redis缓存优化</p>
<ul>
<li><ul>
<li>注意：使用redis缓存一些不经常发生变化的数据。</li>
</ul>
</li>
<li><ul>
<li>数据库的数据一旦发生改变，则需要更新缓存。</li>
</ul>
</li>
<li><ul>
<li>数据库的表执行“增删改”的相关操作，需要将redis缓存数据清空，再次存入。</li>
</ul>
</li>
<li><ul>
<li>在service对应的增删改方法中，将redis数据删除。</li>
</ul>
</li>
<li><p>ProvinceDaoImpl.java</p>
<ul>
<li>public class ProvinceDaoImpl implements ProvinceDao {<br>//1.声明成员变量 jdbctemplement<br>private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());</li>
</ul>
<p>@Override<br>public List<Province> findAll() {<br>  //1.定义sql<br>  String sql = “select * from province “;<br>  //2.执行sql<br>  List<Province> list = template.query(sql, new BeanPropertyRowMapper<Province>(Province.class));<br>  return list;<br>}<br>}<br>ProvinceDao.java<br>package cn.itcast.dao;</p>
</li>
</ul>
</li>
</ul>
<p>import cn.itcast.domain.Province;</p>
<p>import java.util.List;</p>
<p>public interface ProvinceDao {<br>    public List<Province> findAll();<br>}<br>package cn.itcast.domain;<br>Province.java<br>package cn.itcast.domain;</p>
<p>public class Province {</p>
<pre><code>private int id;
private String name;

public int getId() &#123;
    return id;
&#125;

public void setId(int id) &#123;
    this.id = id;
&#125;

public String getName() &#123;
    return name;
&#125;

public void setName(String name) &#123;
    this.name = name;
&#125;
</code></pre><p>}<br>package cn.itcast.jedis;<br>JedisPoolUtils.java<br>package cn.itcast.jedis.util;</p>
<p>import redis.clients.jedis.Jedis;<br>import redis.clients.jedis.JedisPool;<br>import redis.clients.jedis.JedisPoolConfig;</p>
<p>import java.io.IOException;<br>import java.io.InputStream;<br>import java.util.Properties;</p>
<p>/**</p>
<ul>
<li>JedisPool工具类</li>
<li>加载配置文件，配置连接池的参数</li>
<li><p>提供获取连接的方法<br>*/<br>public class JedisPoolUtils {<br> private static JedisPool jedisPool;</p>
<p> static {</p>
<pre><code> //读取配置文件
 InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream(&quot;jedis.properties&quot;);
 //创建Properties对象
 Properties pro = new Properties();
 //关联文件
 try &#123;
     pro.load(is);
 &#125; catch (IOException e) &#123;
     e.printStackTrace();
 &#125;
 //获取数据，设置到JedisPoolConfig中
 JedisPoolConfig config = new JedisPoolConfig();
 //pro.getProperty(&quot;maxTotal&quot;)：获取的值是字符串，配置要求的是int值
 config.setMaxTotal(Integer.parseInt(pro.getProperty(&quot;maxTotal&quot;)));//最大连接数
 config.setMaxIdle(Integer.parseInt(pro.getProperty(&quot;maxIdle&quot;)));//最大空闲连接数
 //初始化JedisPool对象
 jedisPool = new JedisPool(config, pro.getProperty(&quot;host&quot;), Integer.parseInt(pro.getProperty(&quot;port&quot;)));
</code></pre><p> }</p>
<p> /**</p>
<ul>
<li>获取连接方法<br>*/<br>public static Jedis getJedis() {<br> return jedisPool.getResource();//获取连接<br>}<br>}<br>package cn.itcast.service;<br>ProvinceServiceImpl.java<br>package cn.itcast.service.impl;</li>
</ul>
</li>
</ul>
<p>import cn.itcast.dao.ProvinceDao;<br>import cn.itcast.dao.impl.ProvinceDaoImpl;<br>import cn.itcast.domain.Province;<br>import cn.itcast.jedis.util.JedisPoolUtils;<br>import cn.itcast.service.ProvinceService;<br>import com.fasterxml.jackson.core.JsonProcessingException;<br>import com.fasterxml.jackson.databind.ObjectMapper;<br>import redis.clients.jedis.Jedis;</p>
<p>import java.util.List;</p>
<p>public class ProvinceServiceImpl implements ProvinceService {<br>    //声明dao<br>    private ProvinceDao dao = new ProvinceDaoImpl();</p>
<pre><code>@Override
public List&lt;Province&gt; findAll() &#123;
    return dao.findAll();
&#125;

/**
 * 使用redis缓存
 */
@Override
public String findAllJson() &#123;
    //1.先从redis中查询数据
    //1.1获取redis客户端连接
    Jedis jedis = JedisPoolUtils.getJedis();
    String province_json = jedis.get(&quot;province&quot;);
    //2判断 province_json 数据是否为null
    if (province_json == null || province_json.length() == 0) &#123;
        //redis中没有数据
        System.out.println(&quot;redis中没数据，查询数据库...&quot;);
        //2.1从数据中查询
        List&lt;Province&gt; ps = dao.findAll();
        //2.2将list序列化为json
        ObjectMapper mapper = new ObjectMapper();
        try &#123;
            province_json = mapper.writeValueAsString(ps);
        &#125; catch (JsonProcessingException e) &#123;
            e.printStackTrace();
        &#125;
        //2.3 将json数据存入redis
        jedis.set(&quot;province&quot;, province_json);
        //归还连接
        jedis.close();
    &#125; else &#123;
        System.out.println(&quot;redis中有数据，查询缓存...&quot;);
    &#125;
    return province_json;
&#125;
</code></pre><p>}<br>ProvinceService.java<br>package cn.itcast.service;</p>
<p>import cn.itcast.domain.Province;</p>
<p>import java.util.List;</p>
<p>public interface ProvinceService {<br>    public List<Province> findAll();<br>    public String findAllJson();<br>}<br>package cn.itcast.util;<br>JDBCUtils.java<br>package cn.itcast.util;</p>
<p>import com.alibaba.druid.pool.DruidDataSourceFactory;</p>
<p>import javax.sql.DataSource;<br>import java.io.IOException;<br>import java.io.InputStream;<br>import java.sql.Connection;<br>import java.sql.SQLException;<br>import java.util.Properties;</p>
<p>/**</p>
<ul>
<li><p>JDBC工具类 使用Durid连接池<br>*/<br>public class JDBCUtils {<br> private static DataSource ds;</p>
<p> static {</p>
<pre><code> try &#123;
     //1.加载配置文件
     Properties pro = new Properties();
     //使用ClassLoader加载配置文件，获取字节输入流
     InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream(&quot;druid.properties&quot;);
     pro.load(is);
     //2.初始化连接池对象
     ds = DruidDataSourceFactory.createDataSource(pro);
 &#125; catch (IOException e) &#123;
     e.printStackTrace();
 &#125; catch (Exception e) &#123;
     e.printStackTrace();
 &#125;
</code></pre><p> }</p>
<p> /**</p>
<ul>
<li><p>获取连接池对象<br>*/<br>public static DataSource getDataSource() {<br> return ds;<br>}</p>
<p>/**</p>
</li>
<li>获取连接Connection对象<br>*/<br>public static Connection getConnection() throws SQLException {<br> return ds.getConnection();<br>}<br>}<br>package cn.itcast.web;<br>ProvinceServlet.java<br>package cn.itcast.web.servlet;</li>
</ul>
</li>
</ul>
<p>import cn.itcast.service.ProvinceService;<br>import cn.itcast.service.impl.ProvinceServiceImpl;</p>
<p>import javax.servlet.ServletException;<br>import javax.servlet.annotation.WebServlet;<br>import javax.servlet.http.HttpServlet;<br>import javax.servlet.http.HttpServletRequest;<br>import javax.servlet.http.HttpServletResponse;<br>import java.io.IOException;</p>
<p>@WebServlet(“/provinceServlet”)<br>public class ProvinceServlet extends HttpServlet {<br>    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {<br>       /<em> //1.调用service查询<br>        ProvinceService service = new ProvinceServiceImpl();<br>        List<Province> list = service.findAll();<br>        //2.序列化list为json<br>        ObjectMapper mapper = new ObjectMapper();<br>        String json = mapper.writeValueAsString(list);</em>/</p>
<pre><code>    //1.调用service查询
    ProvinceService service = new ProvinceServiceImpl();
    String json = service.findAllJson();

    System.out.println(json);
    //3.响应结果
    response.setContentType(&quot;application/json;charset=utf-8&quot;);
    response.getWriter().write(json);

&#125;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException &#123;
    this.doPost(request, response);
&#125;
</code></pre><p>}<br>web<br>index.html<br>&lt;!DOCTYPE html&gt;</p>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/jquery-3.3.1.min.js"></script>
    <script>
        $(function () {
            //发送ajax请求，加载所有省份数据
            $.get("provinceServlet", {}, function (data) {
                //[{"id":1,"name":"北京"},{"id":2,"name":"上海"},{"id":3,"name":"广州"},{"id":4,"name":"陕西"}]
                //1.获取select
                var province = $("#province");
                //2.遍历json数组
                $(data).each(function () {
                    //3.创建<option>
                    var option = "<option name='" + this.id + "'>" + this.name + "</option>";
                    //4.调用select的append追加option
                    province.append(option);
                });
            });
        });
    </script>
</head>
<body>
    <select id="province">
        <option>--请选择省份--</option>
    </select>
</body>
</html>


      
    </div>
    <footer class="article-footer">
      <a data-url="https://goofyer.gitee.io/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E4%BA%8C%E5%8D%81%E5%85%AB%E7%AB%A0Redis/" data-id="cl403sxr8001kf8vu87tkdtlt" data-title="" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E4%BA%8C%E5%8D%81%E4%B9%9D%E7%AB%A0Maven%E5%9F%BA%E7%A1%80/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          (no title)
        
      </div>
    </a>
  
  
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E4%BA%8C%E5%8D%81%E4%B8%83%E7%AB%A0%20Ajax%E5%92%8CJSON/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title"></div>
    </a>
  
</nav>

  
</article>


</section>
        
          <aside id="sidebar">
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Categories</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/C-%E5%B7%A5%E5%85%B7/">C#工具</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/C-%E5%B7%A5%E5%85%B7/">C++工具</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/Mysql/">Mysql</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/blender/">blender</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/linux/">linux</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/manim/">manim</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/spring/">spring</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/vba%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/">vba基础操作</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E5%88%9B%E9%80%A0%E6%A8%A1%E5%BC%8F/">创造模式</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/">操作系统</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/">操作系统基础知识</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%BC%80%E5%8F%91/">操作系统开发</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%95%B0%E5%AD%A6/">数学</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/">数据结构</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/">数据结构基础知识</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%A8%A1%E6%9D%BF/">模板</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/">深度学习</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%8B%B1%E8%AF%AD/">英语</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%99%9A%E5%B9%BB4/">虚幻4</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/">计算机组成原理</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/">计算机网络</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/notes-on-computer-expertise/tags/C/" rel="tag">C++</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/notes-on-computer-expertise/tags/C/" style="font-size: 10px;">C++</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/05/">May 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/03/">March 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/02/">February 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/01/">January 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2021/12/">December 2021</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/31/vue/%E5%89%8D%E7%AB%AF%E6%A1%86%E6%9E%B6%E9%AA%8C%E8%AF%81%E7%A0%81%E6%97%A0%E6%B3%95%E6%98%BE%E7%A4%BA/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/26/%E6%95%B0%E6%8D%AE%E5%BA%93/navicat%E5%AE%89%E8%A3%85/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/25/%E8%99%9A%E5%B9%BB4%E5%BC%95%E6%93%8E%E5%BC%80%E5%8F%91/%E8%99%9A%E5%B9%BB%E5%9B%9B%20mod%E5%88%B6%E4%BD%9C/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/23/python/python%E6%89%B9%E9%87%8F%E7%94%9F%E6%88%90%E6%95%B0%E6%8D%AE/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/23/vba%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C%E7%AC%94%E8%AE%B0/EXCEL%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/">(no title)</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      
      &copy; 2022 John Doe<br>
      Powered by <a href="https://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>

    </div>
    <nav id="mobile-nav">
  
    <a href="/notes-on-computer-expertise/" class="mobile-nav-link">Home</a>
  
    <a href="/notes-on-computer-expertise/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    


<script src="/notes-on-computer-expertise/js/jquery-3.4.1.min.js"></script>



  
<script src="/notes-on-computer-expertise/fancybox/jquery.fancybox.min.js"></script>




<script src="/notes-on-computer-expertise/js/script.js"></script>





  </div>
<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
        tex2jax: {
            inlineMath: [ ["$","$"], ["\\(","\\)"] ],
            skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'],
            processEscapes: true
        }
    });
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax();
        for (var i = 0; i < all.length; ++i)
            all[i].SourceElement().parentNode.className += ' has-jax';
    });
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML"></script>
</body>
</html>